#ifdef CONFIG_MMC_TESTER
#include "MmcTesterEx.h"
#include "os.h"
#include "ConfigInfoTester.h"
#include "FruInfoTester.h"
#include "Command_Define.h"
#include "IpmbTester.h"
#include "MmcLed.h"
#include "drv_init.h"
#include "Hw.h"

extern uint8 g_FruDeviceBuffer[];

extern int Mmc_ReadFruDevice(FruInfo* pFruInfo, uint32 offset, uint8* pData, uint16 len);

void MmcTester_Reset(MmcTester* pMmcTester)
{
	//memset(pMmcTester->m_pMmc, 0, sizeof(Mmc));
	
	pMmcTester->m_bVerifyResult = False;
	pMmcTester->m_bCrbState = CRB_INIT;

	IicDriverTester_Reset(&pMmcTester->m_IicDriver);
	memset(&pMmcTester->m_ReqPacket, 0, sizeof(pMmcTester->m_ReqPacket));
	pMmcTester->m_pMmc->m_Ipmb.m_pTransfer = (Transfer*)&pMmcTester->m_IicDriver;

	IicDriverTester_Reset(&pMmcTester->m_UartDriver);
	memset(&pMmcTester->m_ReqPacket, 0, sizeof(pMmcTester->m_ReqPacket));
	pMmcTester->m_pMmc->m_UartIpmb.m_pTransfer = (Transfer*)&pMmcTester->m_UartDriver;

}

//input[0] resetState
//input[1] isConfigInfo Valid
//input[2] isFruInfo Valid
//input[3] Ek state

//output[0] wait time
//output[1] read config info count
//output[2] read fru info count
//output[3] Ek state
//output[4] Led State
//output[5] ON time
//output[6] Off time
Bool MmcTester_Start(Mmc* pMmc, uint32 input[], uint32 output[])
{
	uint32 i = 0;
	
	for(i = 0; i < output[0]; i++)
	{
		sleep(1000);
		
	}

	Trace("g_FruReadCounter = %d, g_ConfigReadCounter = %d\n", g_FruReadCounter, g_ConfigReadCounter);
	if(g_FruReadCounter < output[2] || g_ConfigReadCounter < output[1]) return False;

	if(input[0] == POWER_ON_RESET)
	{
		if(g_EkState != 0) return False;
	}
	else
	{
		if(g_EkState != output[3]) return False;
	}

	if(pMmc->m_Led1.m_LedCmd.m_bWorkMode != output[4]) return False;
	if(pMmc->m_Led1.m_LedCmd.m_On != output[5]) return False;
	if(pMmc->m_Led1.m_LedCmd.m_On != output[6]) return False;

	return True;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
Bool MmcTester_VerifyTemp(MmcTester* pMmcTester, SensorTestData* pSensorTestData, EventReqMsg* pEventReqMsg, uint8 Len)
{	
	if(Len != sizeof(EventReqMsg)) return False;
	if(pEventReqMsg->m_SensorId != pSensorTestData->m_SensorId) return False;

	if(pEventReqMsg->m_EventData.m_EventDir != BIT(pSensorTestData->m_Offset, 7)) return False;
	if(pEventReqMsg->m_EventData.m_EventData1.m_Offset != (pSensorTestData->m_Offset & 0x7F)) return False;
	if(pEventReqMsg->m_EventData.m_EventData1.m_Data2Format != 1) return False;
	if(pEventReqMsg->m_EventData.m_EventData1.m_Data3Format != 1) return False;
	if(pEventReqMsg->m_EventData.m_EventData2 != pSensorTestData->m_RawValue) return False;
	if(pEventReqMsg->m_EventData.m_EventData3 != pSensorTestData->m_Threshold) return False;

	return True;
}

Bool MmcTester_VerifyHotSwap(MmcTester* pMmcTester, SensorTestData* pSensorTestData, EventReqMsg* pEventReqMsg, uint8 Len)
{	
	if(Len != sizeof(EventReqMsg)) return False;
	if(pEventReqMsg->m_SensorId != pSensorTestData->m_SensorId) return False;

	if(pEventReqMsg->m_EventData.m_EventData1.m_Offset != pSensorTestData->m_RawValue) return False;
	if(pEventReqMsg->m_EventData.m_EventData1.m_Data2Format != 0) return False;
	if(pEventReqMsg->m_EventData.m_EventData1.m_Data3Format != 0) return False;
	if(pEventReqMsg->m_EventData.m_EventData2 != 0xFF) return False;
	if(pEventReqMsg->m_EventData.m_EventData3 != 0xFF) return False;

	return True;
}

int MmcTester_PlatformEvent(uint8* pReqCmd, uint8 Reqlen, uint8* pRspCmd, uint8* pRspLen)
{
	pRspCmd[0] = COMMAND_COMPLETE;

	* pRspLen = 1;

	return ERR_SUCCESS;
}

const static IpmiCmdHandler g_CmCmdHandler[] = 
{
	{NETFUN_SSEVENT_REQ ,PLATFORM_EVENT_MESSAGE	,(CmdHandlerFun)MmcTester_PlatformEvent}
};

Bool MmcTester_AssertSensorEvent(MmcTester* pMmcTester, SensorTestData* pSensorTestData, VerifyFun verify)
{
	static uint32 nPacketCount = 0;
	int nCount = 0;
	IicMsg* pReqIicMsg = Null;
	BusDataPacket rsp;

	nPacketCount = 0;

	while(nCount < 1000)
	{
		BusDataPacket* pPacket = (BusDataPacket*)QUEUE_popGetHead(&pMmcTester->m_MmcToCmQueue);
		if(pPacket)
		{
			if(nPacketCount++ < pSensorTestData->m_SendReqCount)
			{
				Trace("Send Req Counter=%d\n\n", nPacketCount);
				continue;
			}

			sleep(5);
			pReqIicMsg = (IicMsg*)pPacket->m_Data;

			rsp.m_Len = IpmbTester_CmdDisptch(pReqIicMsg
				, pPacket->m_Len
				, g_CmCmdHandler
				, sizeof(g_CmCmdHandler) / sizeof(IpmiCmdHandler)
				, rsp.m_Data
				, BUS_DATAPACKET_SIZE
				);
			
			Ipmb_driverCallBack(&pMmcTester->m_pMmc->m_Ipmb, EVENT_RX_SUCCESS, rsp.m_Data, rsp.m_Len);
			sleep(50);

			if(Crb_isIdle((Crb*)&pMmcTester->m_pMmc->m_ReqCrb))
			{
				return verify(pMmcTester
					, (ReqData*)pSensorTestData
					, pReqIicMsg->smsgBuf
					, pPacket->m_Len - IICMSG_HEAD_SIZE - 1
					);
			}
		}
		sleep(100);
	}

	return False;
}

Bool MmcTester_SensorTest(MmcTester* pMmcTester, SensorTestData* pSensorTestData, VerifyFun verify)
{
	Sensor* pSensor = Mmc_GetSensor(pSensorTestData->m_SensorId);

	MmcTester_Reset(pMmcTester);

	pSensor->m_ReceiverValue = pSensorTestData->m_CmValue;
	pSensor->m_ReceiverEventData.m_EventData1.m_Offset++;
	Trace("%s,Sensor[%d], CmRawValue=%d\n", _FUNC_, pSensor->m_SensorId, pSensor->m_ReceiverValue);

	//Trace("%s() ,CmRawValue=%d, rawValue=%d\n", _FUNC_, pSensor->m_ReceiverValue, pSensor->m_RawValue);

	pMmcTester->m_pMmc->m_ReceiverAddress = 0x20<<1;
	pMmcTester->m_pMmc->m_ReceiverLun = 0;

	return MmcTester_AssertSensorEvent(pMmcTester, pSensorTestData, verify);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////

void MmcTester_Init(MmcTester* pMmcTester, Mmc* pMmc)
{
	memset(pMmcTester, 0, sizeof(MmcTester));

	pMmcTester->m_pMmc = pMmc;
	
	pMmcTester->m_bVerifyResult = False;
	pMmcTester->m_bCrbState = CRB_INIT;
	//pMmcTester->Verify = Null;
	
	QUEUE_init(&pMmcTester->m_MmcToCmQueue	
		, (uint8*)&pMmcTester->m_MmcToCmQueueBuff	
		, sizeof(BusDataPacket)	
		, MAX_BUS_DATAPACKET);
	QUEUE_init(&pMmcTester->m_CmToMmcQueue	
		, (uint8*)&pMmcTester->m_CmToMmcQueueBuff	
		, sizeof(BusDataPacket)	
		, MAX_BUS_DATAPACKET);
	
	IicDriverTester_Init(&pMmcTester->m_IicDriver
		, 1
		, &pMmcTester->m_CmToMmcQueue
		, &pMmcTester->m_MmcToCmQueue
		, (IicDriverCallBackFun)Ipmb_driverCallBack
		, &pMmc->m_Ipmb);
	
	Ipmb_AttachTransfer(&pMmc->m_Ipmb, (Transfer*)&pMmcTester->m_IicDriver);
///////////////////////
	QUEUE_init(&pMmcTester->m_MmcToPayloadQueue	
		, (uint8*)&pMmcTester->m_MmcToPayloadQueueBuff	
		, sizeof(BusDataPacket)	
		, MAX_BUS_DATAPACKET);
	QUEUE_init(&pMmcTester->m_PayloadToMmcQueue	
		, (uint8*)&pMmcTester->m_PayloadToMmcQueueBuff	
		, sizeof(BusDataPacket)	
		, MAX_BUS_DATAPACKET);
	
	IicDriverTester_Init(&pMmcTester->m_UartDriver
		, 1
		, &pMmcTester->m_PayloadToMmcQueue
		, &pMmcTester->m_MmcToPayloadQueue
		, (IicDriverCallBackFun)Ipmb_driverCallBack
		, &pMmc->m_UartIpmb);
	
	Ipmb_AttachTransfer(&pMmc->m_UartIpmb, (Transfer*)&pMmcTester->m_UartDriver);
	//IicCmd_Init(&pMmcTester->m_IicCmd);
	
}

Bool MmcTester_VerifyGetLocatorRecordId(MmcTester* pMmcTester, ReqData* pReqData, uint8* pRspData, uint8 rspLen)
{
	if(pReqData->m_len < 2 || pReqData->m_len > 4)
	{
		if(pRspData[0] != INVALID_DATA_FILED) return False;
	}

	if(rspLen != 4) return False;

	if(pRspData[2] = 0) return False;
	if(pRspData[3] = 0) return False;

	return True;
}

Bool MmcTester_VerifyGetFruLedSte(MmcTester* pMmcTester, ReqData* pReqData, uint8* pRspData, uint8 rspLen)
{
	uint8 num = 0;
    GET_FRU_LED_STATE_REQ *pReq =(GET_FRU_LED_STATE_REQ *)pReqData->m_buff;
	Led* pLed = Mmc_GetLed(pReq->LED_ID);
	
	if(pReqData->m_len != sizeof(GET_LED_COLOR_CAPABILITIES_REQ))
	{
		if(pRspData[0] != INVALID_DATA_FILED) return False;

		return True;
	}

	if(pLed)
	{
		if(pLed->m_LedStates.m_isLampTestEnabled)
		{
			if(rspLen != 10) return False;
			if(pRspData[2] != AS_UINT8(pLed->m_LedStates)) return False;
			if(pRspData[3] != 0) return False;
			if(pRspData[4] != 0) return False;
			if(pRspData[5] != pLed->m_ColorInLocalCtrlState) return False;
			if(pRspData[6] != LEDFUN_OFF) return False;
			if(pRspData[7] != LEDFUN_ON) return False;
			if(pRspData[8] != pLed->m_ColorInLampTest) return False;
			if(pRspData[9] != pLed->m_LampTestDuration / 100) return False;
		}
		else if(pLed->m_LedStates.m_isOverrideStateEnabled)
		{
			if(rspLen != 9) return False;
			if(pRspData[2] != AS_UINT8(pLed->m_LedStates)) return False;
			if(pRspData[3] != 0) return False;
			if(pRspData[4] != 0) return False;
			if(pRspData[5] != pLed->m_ColorInLocalCtrlState) return False;
			if(pRspData[6] != pLed->m_LedCmd.m_Off / 10) return False;
			if(pRspData[7] != pLed->m_LedCmd.m_On / 10) return False;
			if(pRspData[8] != pLed->m_ColorInOverrideCtrlState) return False;
		}
		else if(pLed->m_LedStates.m_hasALocalCtrlState)
		{
			if(rspLen != 6) return False;
			if(pRspData[2] != AS_UINT8(pLed->m_LedStates)) return False;
			if(pRspData[3] != pLed->m_LedCmd.m_Off / 10) return False;
			if(pRspData[4] != pLed->m_LedCmd.m_On / 10) return False;
			if(pRspData[5] != pLed->m_ColorInLocalCtrlState) return False;
		}
	}
	else
	{
		if(pRspData[0] != REQUESTED_NOT_PRESENT) return False;
	}

	return True;
}

Bool MmcTester_VerifyGetLEDColorCap(MmcTester* pMmcTester, ReqData* pReqData, uint8* pRspData, uint8 rspLen)
{
	GET_LED_COLOR_CAPABILITIES_REQ *pReq = (GET_LED_COLOR_CAPABILITIES_REQ*)pReqData->m_buff;
	GET_LED_COLOR_CAPABILITIES_RSP *pRsp = (GET_LED_COLOR_CAPABILITIES_RSP*)pRspData;
	Led* pLed = Mmc_GetLed(pReq->LED_ID);
	
	if(pReqData->m_len != sizeof(GET_LED_COLOR_CAPABILITIES_REQ))
	{
		if(pRspData[0] != INVALID_DATA_FILED) return False;

		return True;
	}

	if(pLed)
	{
		if(rspLen != sizeof(GET_LED_COLOR_CAPABILITIES_RSP)) return False;

		if(pRsp->LED_Color_Capabilities			!= *(uint8*)&pLed->m_ColorCapabilities) return False;
		if(pRsp->Default_color_Local_state 		!= pLed->m_DefaultColorInLocalCtrlState) return False;
		if(pRsp->Default_color_Override_state 	!= pLed->m_DefaultColorInOverrideCtrlState) return False;
	}
	else
	{
		if(pRsp->m_CompCode != REQUESTED_NOT_PRESENT) return False;
	}

	return True;
}

Bool MmcTester_VerifyLampTest(MmcTester* pMmcTester, ReqData* pReqData, uint8* pRspData, uint8 rspLen)
{
	Bool bFlag = MmcTester_VerifySetLedState(pMmcTester, pReqData, pRspData, rspLen);
	sleep(10000);

	return bFlag;
}

Bool MmcTester_VerifySetLedState(MmcTester* pMmcTester, ReqData* pReqData, uint8* pRspData, uint8 rspLen)
{
	Led* pLed = Null;
    SET_FRU_LED_STATE_REQ *pReq = (SET_FRU_LED_STATE_REQ *)pReqData->m_buff;
    SET_FRU_LED_STATE_RSP* pRsp = (SET_FRU_LED_STATE_RSP*)pRspData;

	sleep(1000);
	if(pReqData->m_len != 6)
	{
		if(pRspData[0] != INVALID_DATA_FILED) return False;

		return True;
	}

	if(0xFF == pReq->LED_ID)
	{
		pLed = Mmc_GetLed(BLUE_LED);
		if(pLed && pLed->m_LedStates.m_isLampTestEnabled != True) return False;
		
		pLed = Mmc_GetLed(LED1_LED);
		if(pLed && pLed->m_LedStates.m_isLampTestEnabled != True) return False;
		return True;
	}

	if(BLUE_LED == pReq->LED_ID && LED1_LED == pReq->LED_ID)
	{
		if(pRspData[0] != REQUESTED_NOT_PRESENT) return False;

		return True;
	}	
	else
	{
		pLed = Mmc_GetLed(pReq->LED_ID);
		if(pReq->LED_Function == LEDFUN_OFF)
		{
			if(pLed->m_LedCmd.m_bWorkMode != OP_OFF)	return False;
		}
		else if(pReq->LED_Function == LEDFUN_ON)
		{
			if(pLed->m_LedCmd.m_bWorkMode != OP_ON)	return False;
		}
		if(pReq->LED_Function >= LEDFUN_SHINE_MIX && pReq->LED_Function <= LEDFUN_SHINE_MAX)
		{
			if(pLed->m_LedCmd.m_bWorkMode != OP_SHINE) return False;
		}
	}

	return True;
}

Bool MmcTester_VerifyGetFruLedProper(MmcTester* pMmcTester, ReqData* pReqData, uint8* pRspData, uint8 rspLen)
{
	if(rspLen != 4 && pRspData[0] != 0) return False;
	if(pRspData[1] != PICMG_IDENTIFIER) return False;
	if(pRspData[2] != (BIT_0|BIT_1)) return False;
	if(pRspData[3] != 1) return False;

	return True;
}

Bool MmcTester_VerifyGetPicmgPorperties(MmcTester* pMmcTester, ReqData* pReqData, uint8* pRspData, uint8 rspLen)
{
	if(rspLen != 5 && pRspData[0] != 0) return False;

	return True;
}

Bool MmcTester_VerifyFruCtrlCap(MmcTester* pMmcTester, ReqData* pReqData, uint8* pRspData, uint8 rspLen)
{
	if(rspLen != 3 && pRspData[0] != 0) return False;

	if(pRspData[2] != AS_UINT8(g_Mmc.m_FruCtrlCapMask)) return False;

	return True;
}

Bool MmcTester_VerifyWriteFruData(MmcTester* pMmcTester, ReqData* pReqData, uint8* pRspData, uint8 rspLen)
{
	uint8 buff[MAX_IPMICMD_DATA_LEN] = {0};
    WriteFruDataReq *pReq = (WriteFruDataReq*)pReqData->m_buff;
	WriteFruDataRsp* pRsp = (WriteFruDataRsp*)pRspData;
    int offset = ((pReq->m_OffsetMs)<<8) | (pReq->m_OffsetLs);
	
	if(pReqData->m_len <= 3)
	{
		if(pRspData[0] != INVALID_DATA_LENGTH) return False;
		return True;
	}

	if(pRsp->m_CompCode != 0) return False;
	if(pRsp->m_Count != pReqData->m_len - 3) return False;

	FruInfo_ReadOffset(&g_Mmc.m_FruInfo, offset, buff, pReqData->m_len - 3);

	if(memcmp(buff, &pReqData->m_buff[3], pReqData->m_len - 3) != 0) return False;

	return True;
}

Bool MmcTester_VerifyReadFruData(MmcTester* pMmcTester, ReqData* pReqData, uint8* pRspData, uint8 rspLen)
{
	int nLen = 0;
    ReadFruDataReq *pReq = (ReadFruDataReq*)pReqData->m_buff;
    int offset = ((pReq->m_OffsetMs)<<8) | (pReq->m_OffsetLs);
	uint8 buff[MAX_IPMICMD_DATA_LEN] = {0};
	
	if(pReqData->m_len != 4)
	{
		if(pRspData[0] != INVALID_DATA_FILED) return False;
		return True;
	}
	
	if(pReq->m_Count > MAX_IPMICMD_DATA_LEN - 2)
	{
		if(pRspData[0] != INVALID_DATA_LENGTH) return False;
		return True;
	}

	if(pReq->m_Count != rspLen - 2) return False;

	nLen = pReq->m_Count;
	FruInfo_ReadOffset(&g_Mmc.m_FruInfo, offset, buff, nLen);

	if(memcmp(&pRspData[2], buff, nLen) != 0) return False;
	
	return True;
}

Bool MmcTester_VerifyGetFruInventory(MmcTester* pMmcTester, ReqData* pReqData, uint8* pRspData, uint8 rspLen)
{
	if(rspLen != 4) return False;
	if(pRspData[0] != COMMAND_COMPLETE) return False;
	if(pRspData[1] != (uint8)g_Mmc.m_FruInfo.m_UsedBufLen) return False;
	if(pRspData[2] != (uint8)(g_Mmc.m_FruInfo.m_UsedBufLen>>8)) return False;
	if(pRspData[3] != 0) return False;

	return True;
}

Bool MmcTester_VerifyReserveDevSdrRepo(MmcTester* pMmcTester, ReqData* pReqData, uint8* pRspData, uint8 rspLen)
{
	if(rspLen != 3) return False;

	if(pRspData[0] != COMMAND_COMPLETE) return False;
	if(pRspData[1] != (uint8)g_Mmc.m_Sdr.m_ReservationId) return False;
	if(pRspData[2] != (uint8)(g_Mmc.m_Sdr.m_ReservationId >> 8)) return False;

	return True;
}

Bool MmcTester_VerifyGetSensorReading(MmcTester* pMmcTester, ReqData* pReqData, uint8* pRspData, uint8 rspLen)
{
    GetSensorReadingRsp* pRsp = (GetSensorReadingRsp*)pRspData;
	Sensor* pSensor = Null;
	
	if(pReqData->m_len != 1)
	{
		if(pRspData[0] != INVALID_DATA_FILED) return False;
		return True;
	}
	
	pSensor = Mmc_GetSensor(pReqData->m_buff[0]);
	if(pSensor)
	{
		if(rspLen != sizeof(GetSensorReadingRsp)) return False;
		if(pRsp->m_CompCode != COMMAND_COMPLETE) return False;
		if(pRsp->m_SensorReading  != pSensor->m_RawValue) return False;
		if(BIT(pRsp->m_Status, 7) != pSensor->m_isEventMsgEnable) return False;
		if(BIT(pRsp->m_Status, 6) != pSensor->m_isScanEnable) return False;
		if(BIT(pRsp->m_Status, 5) != pSensor->m_isReadingUnavailable) return False;
		if(pRsp->m_ComparisonStatus1 != (uint8)pSensor->m_ReadingEvent) return False;
		if(pRsp->m_ComparisonStatus2 != (uint8)(pSensor->m_ReadingEvent>>8)) return False;
	}
	else
	{
		if(pRspData[0] != REQUESTED_NOT_PRESENT) return False;
		return True;
	}

	return True;
}

Bool MmcTester_VerifyGetDeviceSdr(MmcTester* pMmcTester, ReqData* pReqData, uint8* pRspData, uint8 rspLen)
{
	uint8 maxSize = MAX_IPMICMD_DATA_LEN;
	uint8 buff[MAX_IPMICMD_DATA_LEN] = {0};
	GetDeviceSdrRsq* pRsp = (GetDeviceSdrRsq*)pRspData;
	GetDeviceSdrReq* pReq = (GetDeviceSdrReq*)pReqData->m_buff;
	uint8 len = pReq->m_Len;
	uint16 reqRecordId = (pReq->m_RecordIdMs<<8) | pReq->m_RecordIdLs;
	uint16 reservationId = (pReq->m_ReservationIdMs<<8) | pReq->m_ReservationIdLs;
	uint16 rspNextRecord = (pRsp->m_NextIdMs<<8) | pRsp->m_NextIdLs;
	uint16 nextRecord = 0;

	if(pReq->m_Len == 0xFF) len = maxSize;

	if(pReqData->m_len != sizeof(GetDeviceSdrReq))
	{
		if(pRspData[0] != INVALID_DATA_FILED && rspLen != 1) return False;
		return True;
	}

	if(pReq->m_Offset > 0)
	{
		if(reservationId != pMmcTester->m_pMmc->m_Sdr.m_ReservationId)
		{
			if(pRsp->m_CompCode != INVALID_RESERVED_ID) return False;
			return True;
		}
	}

	if(rspLen > maxSize) return False;
	
	if(pReq->m_Len != 0xFF && pReq->m_Len > maxSize)
	{
		if(pRspData[0] != CANNOT_RETURN_NUMBRE_OF_DATA) return False;
		return True;
	}
	
	
	len = rspLen - 3;
	len = Sdr_GetRecord(&pMmcTester->m_pMmc->m_Sdr, reqRecordId, &nextRecord, pReq->m_Offset, buff, len);

	if(rspNextRecord != nextRecord) return False;

	if(memcmp(pRsp->m_Buff, buff, len) != 0) return False;

	return True;
}

Bool MmcTester_VerifyGetDeviceSdrInfo(MmcTester* pMmcTester, ReqData* pReq, uint8* pRspData, uint8 rspLen)
{
	if(rspLen != sizeof(GetDeviceSDRInfoRsp)) return False;
	if(pRspData[0] != 0) return False;

	if((pReq->m_len >= 1) && (pReq->m_buff[0] & 0x01))	//Get Sdr Count
	{
		if(pRspData[1] != (uint8)Sdr_GetSdrCount(&g_Mmc.m_Sdr, False)) return False;
	}
	else if(pRspData[1] != (uint8)Sdr_GetSdrCount(&g_Mmc.m_Sdr, True))
	{
		return False;
	}

	if(BIT(pRspData[2], 7) != 0) return False;
	if(BIT(pRspData[2], 0) != 1) return False;

	return True;
}

Bool MmcTester_VerifyGetEventReceiver(MmcTester* pMmcTester, ReqData* pReq, uint8* pRspData, uint8 rspLen)
{
	if(rspLen != 3) return False;
	if(pRspData[0] != 0) return False;

	if(g_Mmc.m_ReceiverAddress != pRspData[1]) return False;
	if(g_Mmc.m_ReceiverLun != (pRspData[2] & 0x03)) return False;

	return True;
}

Bool MmcTester_VerifySetEventReceiver(MmcTester* pMmcTester, ReqData* pReq, uint8* pRspData, uint8 rspLen)
{
	if(pReq->m_len != 2)
	{
		if(pRspData[0] == COMMAND_COMPLETE) return False;
		return True;
	}
	if(rspLen != 1) return False;
	if(pRspData[0] != 0) return False;

	if(g_Mmc.m_ReceiverAddress != pReq->m_buff[0]) return False;
	if(g_Mmc.m_ReceiverLun != (pReq->m_buff[1] & 0x03)) return False;

	return True;
}

Bool MmcTester_VerifyGetDeviceId(MmcTester* pMmcTester, ReqData* pReq, uint8* pRspData, uint8 rspLen)
{
	GetDeviceIDRsp* pRsp = (GetDeviceIDRsp*)pRspData;

	if(rspLen != sizeof(GetDeviceIDRsp)) return False;
	if(pRsp->CompCode != 0) return False;
	if(pRsp->Device_ID != 0) return False;
	
	if(pRsp->Device_Revision != pMmcTester->m_pMmc->m_DeviceRev) return False;
	if(pRsp->Firmware_Revision_1 != pMmcTester->m_pMmc->m_FirmwareMasterRev) return False;
	if(pRsp->Firmware_Revision_2 != pMmcTester->m_pMmc->m_FirmwareSubRev) return False;
	if(pRsp->IPMI_Version != pMmcTester->m_pMmc->m_IpmiRev) return False;

	if(pRsp->EventGenerator != 1) return False;
	if(pRsp->FRUInventoryDevice != 1) return False;
	if(pRsp->SDRRepositoryDevice != 1) return False;
	if(pRsp->SensorDevice != 1) return False;

	return True;
}

Bool MmcTester_VerifySetPortState(MmcTester* pMmcTester, ReqData* pReq, uint8* pRspData, uint8 rspLen)
{
    SET_PORT_STATE_RSP* pRsp = (SET_PORT_STATE_RSP*)pRspData;

    if(rspLen != sizeof(SET_PORT_STATE_RSP)) return False;
    if(pRsp->m_CompCode != 0) return False;
    if(pRsp->PICMG_ID != 0) return False;

    return True;
}

Bool MmcTester_VerifyGetPortState(MmcTester* pMmcTester, ReqData* pReq, uint8* pRspData, uint8 rspLen)
{
    GET_PORT_STATE_RSP* pRsp = (GET_PORT_STATE_RSP*)pRspData;

    if(rspLen != sizeof(GET_PORT_STATE_RSP)) return False;
    if(pRsp->m_CompCode != 0) return False;
    if(pRsp->PICMG_ID != 0) return False;

    return True;
}


Bool MmcTester_Verify(MmcTester* pMmcTester, ReqData* pReq, uint8* pRspData, uint8 rspLen)
{
	return True;
}

void MmcTester_CrbDone(MmcTester* pMmcTester, Crb* pCrb, uint8 State)
{
	IpmiHeader* pHeader = (IpmiHeader*)pCrb->m_pReqIpmiCmd;
	uint8 cmd = pHeader->m_Cmd;
	
	pMmcTester->m_bCrbState = State;

	if(pMmcTester->m_bCrbState == CRB_RX_RSP_SUCCESS)
	{
		pMmcTester->m_bVerifyResult = True;
	}
}

Bool MmcTester_SendReqToMmc(MmcTester* pMmcTester, ReqData* pReq)
{
	int nRet = 0;
	Mmc* pMmc = pMmcTester->m_pMmc;
	
	memset(&pMmcTester->m_ReqPacket, 0, sizeof(BusDataPacket));
	
	pMmcTester->m_ReqPacket.m_Len = IpmbTester_GetCmReq(pReq
		, pMmc->m_RspCrb.m_LocalAddr
		, pMmc->m_RspCrb.m_RemoteAddr
		, (IicMsg*)pMmcTester->m_ReqPacket.m_Data
		, BUS_DATAPACKET_SIZE);

	Trace("IicDriver receive data, cmd=0x%x, netFun=0x%x", pReq->m_Cmd, pReq->m_NetFn);
	Debug_DumpByteEx(TRACE_MAIN, pMmcTester->m_ReqPacket.m_Data, pMmcTester->m_ReqPacket.m_Len, 32, " ", 0);
	return ERR_SUCCESS == Ipmb_driverCallBack(&pMmc->m_Ipmb, EVENT_RX_SUCCESS, (uint8*)pMmcTester->m_ReqPacket.m_Data, pMmcTester->m_ReqPacket.m_Len);
}

Bool MmcTester_PayloadSendReqToMmc(MmcTester* pMmcTester, ReqData* pReq)
{
	int nRet = 0;
	Mmc* pMmc = pMmcTester->m_pMmc;
	
	memset(&pMmcTester->m_ReqPacket, 0, sizeof(BusDataPacket));
	
	pMmcTester->m_ReqPacket.m_Len = IpmbTester_GetCmReq(pReq
		, pMmc->m_UartReqCrb.m_LocalAddr
		, pMmc->m_UartRspCrb.m_RemoteAddr
		, (IicMsg*)pMmcTester->m_ReqPacket.m_Data
		, BUS_DATAPACKET_SIZE);

	Trace("IicDriver receive data, cmd=0x%x, netFun=0x%x", pReq->m_Cmd, pReq->m_NetFn);
	Debug_DumpByteEx(TRACE_MAIN, pMmcTester->m_ReqPacket.m_Data, pMmcTester->m_ReqPacket.m_Len, 32, " ", 0);
	return ERR_SUCCESS == Ipmb_driverCallBack(&pMmc->m_UartIpmb
		, EVENT_RX_SUCCESS
		, (uint8*)pMmcTester->m_ReqPacket.m_Data
		, pMmcTester->m_ReqPacket.m_Len
		);
}

Bool MmcTester_SetEventReceiver(MmcTester* pMmcTester, ReqData* pReq, VerifyFun verify, uint32 output[])
{
	uint8 isReceRsp = False;
	BusDataPacket* pTemp;
	BusDataPacket* pPacket = Null;
	Bool bFlag = False;
	int nCount = 0;
	int nReceReqCounter = 0;
	Crb* pCrb = (Crb*)&pMmcTester->m_pMmc->m_ReqCrb;
	BusDataPacket dataPacket={0};
	BusDataPacket rspPacket={0};
	IicMsg* pMsg = Null;

	MmcTester_Reset(pMmcTester);

	pReq->Notify = (CrbNotifyFun)MmcTester_CrbDone;
	pReq->m_pRequester = pMmcTester;
	
	while(nCount++ < 300)
	{
		if(!bFlag)
		{
			//nCount = 0;
			bFlag = MmcTester_SendReqToMmc(pMmcTester, pReq);
			if(pReq->m_len + MAX_IPMICMD_DATA_LEN + 1 > pMmcTester->m_pMmc->m_ReqCrb.m_Base.m_pReqIpmiCmd->m_MaxLen)
			{
				if(bFlag == FALSE) return True;
			}
		}

		pPacket = (BusDataPacket*)QUEUE_popGetHead(&pMmcTester->m_MmcToCmQueue);
		pMsg = (IicMsg*)pPacket->m_Data;
		if(rspPacket.m_Len && !isReceRsp)
		{
			if(Crb_isIdle((Crb*)&pMmcTester->m_pMmc->m_RspCrb))
			{
				//TRACE_LINE();
				isReceRsp = True;
				if(verify)
				{
					pMmcTester->m_bVerifyResult = verify(pMmcTester
						, pReq
						, ((IicMsg*)rspPacket.m_Data)->smsgBuf
						, rspPacket.m_Len - IICMSG_HEAD_SIZE - 1
						);
				}
				else
				{
					pMmcTester->m_bVerifyResult = True;
				}
				if(output[0] == 0)
				{
					break;
				}
			}			
		}
		else if(pPacket && !isReceRsp && !IS_REQUEST_NETFUN(pMsg->rsNetFn))
		{
			//TRACE_LINE();
			rspPacket.m_Len = pPacket->m_Len;
			memcpy(rspPacket.m_Data, pPacket->m_Data, pPacket->m_Len);
			continue;
		}

		pTemp = pPacket;
		while(pTemp)
		{
			pTemp = (BusDataPacket*)QUEUE_popGetHead(&pMmcTester->m_MmcToCmQueue);
			if(pTemp)
				pPacket = pTemp;
		};
		
		pMsg = (IicMsg*)pPacket->m_Data;
		if(pPacket && IS_REQUEST_NETFUN(pMsg->rsNetFn))
		{
			if(output[0])
			{	
				uint8 buf[5] = {0};
				//TRACE_LINE();
				pMmcTester->m_bVerifyResult = True;
				dataPacket.m_Data[0]=0;
				dataPacket.m_Len = IicMsg_GetRsp(pMsg, dataPacket.m_Data, BUS_DATAPACKET_SIZE, buf, 1);
				Ipmb_driverCallBack(&pMmcTester->m_pMmc->m_Ipmb, EVENT_RX_SUCCESS, dataPacket.m_Data, dataPacket.m_Len);
				if(++nReceReqCounter >= output[0])
				{
					pMmcTester->m_bVerifyResult = True;
					//break;
				}
			}
		}

		sleep(1);
	};

	return (bFlag && pMmcTester->m_bVerifyResult);
}

Bool MmcTester_cmdEx(MmcTester* pMmcTester, ReqData* pReq, VerifyFun verify, uint32 output[])
{
	BusDataPacket* pPacket = Null;
	Bool bFlag = False;
	int nCount = 0;
	Crb* pCrb = (Crb*)&pMmcTester->m_pMmc->m_ReqCrb;
	BusDataPacket payloadPacket={0};

	MmcTester_Reset(pMmcTester);

	pReq->Notify = (CrbNotifyFun)MmcTester_CrbDone;
	pReq->m_pRequester = pMmcTester;
	
	while(True || nCount++ >= 100)
	{
		if(!bFlag)
		{
			nCount = 0;
			bFlag = MmcTester_SendReqToMmc(pMmcTester, pReq);
			if(pReq->m_len + MAX_IPMICMD_DATA_LEN + 1 > pMmcTester->m_pMmc->m_ReqCrb.m_Base.m_pReqIpmiCmd->m_MaxLen)
			{
				if(bFlag == FALSE) return True;
			}
		}

		if(Crb_isIdle((Crb*)&pMmcTester->m_pMmc->m_RspCrb))
		{
			pPacket = (BusDataPacket*)QUEUE_popGetHead(&pMmcTester->m_MmcToCmQueue);
			if(pPacket)
			{
				IicMsg* pReqMsg = (IicMsg*)pMmcTester->m_ReqPacket.m_Data;
				IicMsg* pRspMsg = (IicMsg*)pPacket->m_Data;

				if(verify)
				{
					pMmcTester->m_bVerifyResult = verify(pMmcTester
						, pReq
						, pRspMsg->smsgBuf
						, pPacket->m_Len - IICMSG_HEAD_SIZE - 1
						);
				}
				else
				{
					pMmcTester->m_bVerifyResult = True;
				}
				
				if(!output[0])
				{
					break;
				}
			}
		}

		if(output[0])
		{
			if(pMmcTester->m_pMmc->m_UartIpmb.m_pTxCrb == Null)
			{
				pPacket = (BusDataPacket*)QUEUE_popGetHead(&pMmcTester->m_MmcToPayloadQueue);
				if(pPacket)
				{
					uint8 buf[5] = {0};
					IicMsg* pReqMsg = (IicMsg*)pPacket->m_Data;
					
					payloadPacket.m_Len = IicMsg_GetRsp(pReqMsg, payloadPacket.m_Data, BUS_DATAPACKET_SIZE, buf, 1);
					Ipmb_driverCallBack(&pMmcTester->m_pMmc->m_UartIpmb, EVENT_RX_SUCCESS, payloadPacket.m_Data, payloadPacket.m_Len);
				}
			}

			if(payloadPacket.m_Len && Crb_isIdle((Crb*)&pMmcTester->m_pMmc->m_UartReqCrb))
			{
				return True;
			}
		}
		sleep(5);
	};

	return (bFlag && pMmcTester->m_bVerifyResult);
}

Bool MmcTester_cmd(MmcTester* pMmcTester, ReqData* pReq, VerifyFun verify)
{
	BusDataPacket* pPacket = Null;
	Bool bFlag = False;
	int nCount = 0;
	Crb* pCrb = (Crb*)&pMmcTester->m_pMmc->m_ReqCrb;

	MmcTester_Reset(pMmcTester);

	pReq->Notify = (CrbNotifyFun)MmcTester_CrbDone;
	pReq->m_pRequester = pMmcTester;
	
	while(True || nCount++ >= 100)
	{
		if(!bFlag)
		{
			nCount = 0;
			bFlag = MmcTester_SendReqToMmc(pMmcTester, pReq);
			if(pReq->m_len + MAX_IPMICMD_DATA_LEN + 1 > pMmcTester->m_pMmc->m_ReqCrb.m_Base.m_pReqIpmiCmd->m_MaxLen)
			{
				if(bFlag == FALSE) return True;
			}
		}

		if(Crb_isIdle((Crb*)&pMmcTester->m_pMmc->m_RspCrb))
		{
			pPacket = (BusDataPacket*)QUEUE_popGetHead(&pMmcTester->m_MmcToCmQueue);
			if(pPacket)
			{
				IicMsg* pReqMsg = (IicMsg*)pMmcTester->m_ReqPacket.m_Data;
				IicMsg* pRspMsg = (IicMsg*)pPacket->m_Data;

				if(verify)
				{
					pMmcTester->m_bVerifyResult = verify(pMmcTester
						, pReq
						, pRspMsg->smsgBuf
						, pPacket->m_Len - IICMSG_HEAD_SIZE - 1
						);
				}
				else
				{
					pMmcTester->m_bVerifyResult = True;
				}
				
				break;
			}
		}

		sleep(5);
	};

	return (bFlag && pMmcTester->m_bVerifyResult);

}

Bool MmcTester_payloadCmd(MmcTester* pMmcTester, ReqData* pReq, VerifyFun verify)
{
	BusDataPacket* pPacket = Null;
	Bool bFlag = False;
	int nCount = 0;
	Crb* pCrb = (Crb*)&pMmcTester->m_pMmc->m_UartReqCrb;
	IpmiCmd* pIpmiCmd = pCrb->m_pReqIpmiCmd;

	MmcTester_Reset(pMmcTester);

	pReq->Notify = (CrbNotifyFun)MmcTester_CrbDone;
	pReq->m_pRequester = pMmcTester;
	
	while(True || nCount++ >= 100)
	{
		if(!bFlag)
		{
			nCount = 0;
			bFlag = MmcTester_PayloadSendReqToMmc(pMmcTester, pReq);
			if(pReq->m_len + MAX_IPMICMD_DATA_LEN + 1 > pIpmiCmd->m_MaxLen)
			{
				if(bFlag == FALSE) return True;
			}
		}

		if(Crb_isIdle((Crb*)&pMmcTester->m_pMmc->m_UartRspCrb))
		{
			pPacket = (BusDataPacket*)QUEUE_popGetHead(&pMmcTester->m_MmcToPayloadQueue);
			if(pPacket)
			{
				IicMsg* pReqMsg = (IicMsg*)pMmcTester->m_ReqPacket.m_Data;
				IicMsg* pRspMsg = (IicMsg*)pPacket->m_Data;

				if(verify)
				{
					pMmcTester->m_bVerifyResult = verify(pMmcTester
						, pReq
						, pRspMsg->smsgBuf
						, pPacket->m_Len - IICMSG_HEAD_SIZE - 1
						);
				}
				else
				{
					pMmcTester->m_bVerifyResult = True;
				}
				
				break;
			}
		}

		sleep(5);
	};

	return (bFlag && pMmcTester->m_bVerifyResult);

}
#endif	//#ifdef CONFIG_MMC_TESTER

